package com.nio.netty.dubborpc.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;
import java.util.concurrent.Callable;

public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context;
    private String result;/*返回的结果*/
    private String para;/*客户端调用方法时，传入的参数*/

    /*2*/
    public void setPara(String para) {
        System.out.printf("[%tF %<tT] setPara被调用！\n",new Date());
        this.para = para;
    }

    @Override /*1*/
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.printf("[%tF %<tT] channelActive被调用！\n",new Date());
        context=ctx;/*因为我们在其他方法会使用到这个ctx*/
    }

    @Override /*4*/
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.printf("[%tF %<tT] channelRead被调用！\n",new Date());
        result= (String) msg;
        notify();/*唤醒等待的线程*/
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    /*被代理对象调用， 发送数据给服务器->wait->等待被唤醒（被channelRead唤醒）->返回结果 3 5*/
    @Override
    public synchronized Object call() throws Exception {
        System.out.printf("[%tF %<tT] call1被调用！\n",new Date());
        context.writeAndFlush(para);
        /*没有马上返回消息，进行wait*/
        wait();/*等待channelRead  方法获取到服务器的结果后，被唤醒*/
        System.out.printf("[%tF %<tT] call2被调用！\n",new Date());
        return result;/*服务器返回的结果*/
    }
}
